package com.why.sharding.complex;

import com.why.sharding.util.StringUtils;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;

import java.util.*;

/**
 * @description: 复合分片算法
 * @author: wanghongyu | stan.wang@paytm.com
 * @create: 2022/01/19
 **/
public class OrderDbComplex implements ComplexKeysShardingAlgorithm<Long> {

    private Properties props = new Properties();

    /**
     * 功能描述： 实现分片的具体实现,数据库根据用户ID和订单ID来实现分片，
     *          意味着只要某张表中应用了这个复合分片算法，然后字段里面有包含用户ID
     *          和订单ID的SQL那就会实现数据库的分片。
     * @param collection
     * @param complexKeysShardingValue
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        List<String> shardingList = new ArrayList();
        // 获取请求参数
        Map<String, Collection<Long>> columnNameAndShardingValuesMap = complexKeysShardingValue.getColumnNameAndShardingValuesMap();
        List orderIdList = (List) columnNameAndShardingValuesMap.get("order_id");
        List userIdList = (List) columnNameAndShardingValuesMap.get("user_id");
        Long order_id = orderIdList != null ? StringUtils.getObjLong(orderIdList.get(0)) : 0L;
        Long user_id = userIdList != null ? StringUtils.getObjLong(userIdList.get(0)) : 0L;
        Long modVal = 0L;
        // 分片的规则首先以订单ID进行分片
        if (order_id > 0L) {
            modVal = order_id % 2;
        }
        // 若订单ID和用户ID同时存在的情况下，以用户ID进行分片
        if (user_id > 0L) {
            modVal = user_id % 2;
        }
        for (String str : collection) {
            if (("db" + modVal).equals(str)) {
                shardingList.add(str);
            }
        }
        return shardingList;
    }

    /**
     * 初始化当前对象的时候调用的方法
     */
    @Override
    public void init() {

    }

    /**
     * 功能描述： 对应sharding-algorithms配置里面的type属性里面配置的值
     *
     * @return
     */
    @Override
    public String getType() {
        return "OrderDbComplex";
    }

    @Override
    public Properties getProps() {
        return this.props;
    }

    /**
     * 功能描述： 获取application.yml中的当前分片算法的配置信息
     *
     * @param properties application.yml中的当前分片算法的配置信息
     */
    @Override
    public void setProps(Properties properties) {
        this.props = properties;
    }
}
